package com.bsg.upm.service;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.check.UserCheck;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.dto.UserDto;
import com.bsg.upm.dto.UserGroupDto;
import com.bsg.upm.dto.UserRoleDto;
import com.bsg.upm.entity.BusinessSubSystemEntity;
import com.bsg.upm.entity.BusinessSystemEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.entity.UserGroupEntity;
import com.bsg.upm.entity.UserRoleEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.EncryptionUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 用户注册业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class UserService extends BaseService {

	@Resource
	private UserRoleService userRoleService;

	@Resource
	private UserGroupService userGroupService;

	@Resource
	private UserCheck userCheck;

	/**
	 * 用户查询
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(Map<String, Object> paramMap) throws APIException {
		try {
			// 结果集
			JSONArray results = new JSONArray();

			// 获取指定条件的用户
			List<UserEntity> users = userDao.list(paramMap);

			for (UserEntity user : users) {
				// 构建用户展示对象
				UserDto userDto = buildShowDto(user, false);
				results.add(userDto);
			}
			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("用户查询异常", e);
			throw new APIException("用户查询异常:" + e.getMessage());
		}
	}

	/**
	 * 用户详情
	 * 
	 * @param username
	 *            用户名
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String username) throws APIException {
		try {
			// 获取指定的用户
			UserEntity user = userDao.getUser(username, null);

			if (user == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该用户不存在");
			}

			// 构建用户展示对象
			UserDto userDto = buildShowDto(user, true);

			return RespJsonFactory.buildOK(userDto);
		} catch (Exception e) {
			logger.error("用户获取异常", e);
			throw new APIException("用户获取异常:" + e.getMessage());
		}
	}

	/**
	 * 用户注册
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson save(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REGISTER;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 用户注册检查
			CheckResult chkRS = userCheck.checkSave(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建用户对象
			UserEntity user = buildUser(paramMap);
			userDao.save(user);

			BusinessSystemEntity businessSystem = buildDefaultBusinessSystem(user);
			businessSystemDao.save(businessSystem);

			BusinessSubSystemEntity businessSubSystem = buildDefaultBusinessSubSystem(businessSystem);
			businessSubSystemDao.save(businessSubSystem);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion, user.getUsername(), user.getName(),
					user.getUsername(), user.getCreateDatetime());

			return RespJsonFactory.buildCreated();
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * SSO用户注册
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 操作结果
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson saveSSO(Map<String, Object> paramMap) throws APIException {
		String operateAcion = OperateDictConstants.ACTION_REGISTER;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// check
			String username = (String) paramMap.get("username");
			if (StringUtils.isBlank(username)) {
				return RespJsonFactory.build(HttpStatus.SC_BAD_REQUEST, "用户名不能为空");
			}

			String password = (String) paramMap.get("password");
			if (StringUtils.isBlank(password)) {
				return RespJsonFactory.build(HttpStatus.SC_BAD_REQUEST, "密码不能为空");
			}

			String group = (String) paramMap.get("group");
			if (StringUtils.isBlank(group)) {
				return RespJsonFactory.build(HttpStatus.SC_BAD_REQUEST, "机构不能为空");
			}

			// UserEntity user = buildUser(paramMap);
			// userDao.save(user);
			//
			// // 保存操作日志
			// saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion,
			// user.getUsername(), user.getName(),
			// user.getUsername(), user.getCreateDatetime());

			return RespJsonFactory.build(HttpStatus.SC_FORBIDDEN, "未开发");
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 用户编辑
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson update(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 用户编辑检查
			CheckResult chkRS = userCheck.checkUpdate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建用户对象
			UserEntity user = buildUserToUpdate(paramMap);
			userDao.update(user);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion, user.getUsername(), user.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 密码变更
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson updatePwd(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE_PWD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 用户编辑检查
			CheckResult chkRS = userCheck.checkUpdatePwd(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			UserEntity user = userDao.getUser((String) paramMap.get("username"), null);
			user.setPassword(EncryptionUtils.getMD5((String) paramMap.get("newPassword")));
			userDao.updatePwd(user);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion, user.getUsername(), user.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}
	
	/**
	 * 密码重置
	 * 
	 * @param username
	 *            用户名
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson resetPwd(String username) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_RESET_PWD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的用户
			UserEntity user = userDao.getUser(username, null);
			
			// 用户重置密码检查
			CheckResult chkRS = userCheck.checkResetPwd(user);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			user.setPassword(EncryptionUtils.getMD5("000000"));
			userDao.updatePwd(user);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion, user.getUsername(), user.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 用户启用/停用
	 * 
	 * @param username
	 *            用户名
	 * @param enable
	 *            是否启用
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson enable(String username, boolean enable) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_DISABLE;
		if (enable) {
			operateAcion = OperateDictConstants.ACTION_ENABLE;
		}
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的用户
			UserEntity user = userDao.getUser(username, null);

			// 用户启停检查
			CheckResult chkRS = null;
			if (enable) {
				chkRS = userCheck.checkEnable(user);
			} else {
				chkRS = userCheck.checkDisable(user);
			}
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 设置启停状态
			user.setEnabled(enable);
			userDao.updateEnabled(user);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER, operateAcion, user.getUsername(), user.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("用户" + operateAcionText + "异常", e);
			throw new APIException("用户" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 构建用户展示对象
	 * 
	 * @param user
	 *            用户
	 * @param showDetail
	 *            是否展示详情
	 * @return 用户展示对象
	 */
	private UserDto buildShowDto(UserEntity user, boolean showDetail) {
		UserDto userDto = buildUserBaseDto(user);

		UserRoleEntity role = user.getUserRole();
		if (role != null) {
			UserRoleDto roleDto = userRoleService.buildRoleBaseDto(role);
			userDto.setRole(roleDto);
		}

		UserGroupEntity group = user.getUserGroup();
		if (group != null) {
			UserGroupDto groupDto = userGroupService.buildGroupBaseDto(group);
			userDto.setGroup(groupDto);
		}
		return userDto;
	}

	/**
	 * 构建用户基础展示对象
	 * 
	 * @param user
	 *            用户
	 * @param showDetail
	 *            是否展示详情
	 * @return 用户基础展示对象
	 */
	public UserDto buildUserBaseDto(UserEntity user) {
		UserDto userDto = new UserDto();
		userDto.setUsername(user.getUsername());
		userDto.setName(user.getName());
		userDto.setTelephone(user.getTelephone());
		userDto.setEmail(user.getEmail());
		userDto.setCompany(user.getCompany());
		userDto.setEnabled(user.getEnabled());
		userDto.setAuthType(user.getAuthType());
		userDto.setAutoApprove(user.getAutoApprove());
		userDto.setAlternateContact(user.getAlternateContact());
		userDto.setAlternateContactTel(user.getAlternateContactTel());
		userDto.setRegisterDatetime(DateUtils.dateTimeToString(user.getCreateDatetime()));
		return userDto;
	}

	/**
	 * 构建用户对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 用户对象
	 */
	private UserEntity buildUser(Map<String, Object> paramMap) {
		UserEntity user = new UserEntity();
		user.setUsername(StringUtils.trim((String) paramMap.get("username")));
		user.setPassword(EncryptionUtils.getMD5((String) paramMap.get("password")));
		user.setName(StringUtils.trim((String) paramMap.get("name")));
		user.setTelephone(StringUtils.trim((String) paramMap.get("telephone")));
		user.setEmail(StringUtils.trim((String) paramMap.get("email")));
		user.setCompany(StringUtils.trim((String) paramMap.get("company")));
		user.setAlternateContact(StringUtils.trim((String) paramMap.get("alternateContact")));
		user.setAlternateContactTel(StringUtils.trim((String) paramMap.get("alternateContactTel")));
		user.setAutoApprove((Boolean) paramMap.get("autoApprove"));
		user.setEnabled(true);
		user.setAuthType("native");
		user.setCreateDatetime(systemDao.getCurrentDateTime());

		UserRoleEntity role = new UserRoleEntity();
		role.setCode(StringUtils.trim((String) paramMap.get("role")));
		user.setUserRole(role);

		if (paramMap.containsKey("group") && StringUtils.isNotBlank(StringUtils.trim((String) paramMap.get("group")))) {
			UserGroupEntity group = new UserGroupEntity();
			group.setId(StringUtils.trim((String) paramMap.get("group")));
			user.setUserGroup(group);
		}
		return user;
	}

	/**
	 * 构建用户对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 用户对象
	 */
	private UserEntity buildUserToUpdate(Map<String, Object> paramMap) {
		UserEntity user = userDao.getUser((String) paramMap.get("username"), null);
		if (paramMap.containsKey("name")) {
			user.setName(StringUtils.trim((String) paramMap.get("name")));
		}

		if (paramMap.containsKey("telephone")) {
			user.setTelephone(StringUtils.trim((String) paramMap.get("telephone")));
		}

		if (paramMap.containsKey("email")) {
			user.setEmail(StringUtils.trim((String) paramMap.get("email")));
		}

		if (paramMap.containsKey("company")) {
			user.setCompany(StringUtils.trim((String) paramMap.get("company")));
		}

		if (paramMap.containsKey("alternateContact")) {
			user.setAlternateContact(StringUtils.trim((String) paramMap.get("alternateContact")));
		}

		if (paramMap.containsKey("alternateContactTel")) {
			user.setAlternateContactTel(StringUtils.trim((String) paramMap.get("alternateContactTel")));
		}

		if (paramMap.containsKey("autoApprove")) {
			user.setAutoApprove((Boolean) paramMap.get("autoApprove"));
		}

		if (paramMap.containsKey("roleCode")) {
			UserRoleEntity userRole = new UserRoleEntity();
			userRole.setCode((String) paramMap.get("roleCode"));
			user.setUserRole(userRole);
		}

		if (paramMap.containsKey("group")) {
			UserGroupEntity group = new UserGroupEntity();
			group.setId(StringUtils.trim((String) paramMap.get("group")));
			user.setUserGroup(group);
		}

		return user;
	}

	/**
	 * 构建用户默认业务系统对象
	 * 
	 * @param user
	 *            用户对象
	 * @return 业务系统对象
	 */
	private BusinessSystemEntity buildDefaultBusinessSystem(UserEntity user) {
		BusinessSystemEntity businessSystem = new BusinessSystemEntity();
		businessSystem.setId(PrimaryKeyUtils.uniqueId());
		businessSystem.setName("默认业务系统");
		businessSystem.setCreateDateTime(user.getCreateDatetime());
		businessSystem.setOwner(user.getUsername());
		return businessSystem;
	}

	/**
	 * 构建用户默认业务子系统
	 * 
	 * @param businessSystem
	 *            业务系统
	 * @return 业务子系统对象
	 */
	private BusinessSubSystemEntity buildDefaultBusinessSubSystem(BusinessSystemEntity businessSystem) {
		BusinessSubSystemEntity businessSubSystem = new BusinessSubSystemEntity();
		businessSubSystem.setId(PrimaryKeyUtils.uniqueId());
		businessSubSystem.setName("默认业务子系统");
		businessSubSystem.setBusinessSystem(businessSystem);
		businessSubSystem.setCreateDateTime(businessSystem.getCreateDateTime());
		return businessSubSystem;
	}

}
